﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Common;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using WqLunTan.Areas.Manage.Models;
using WqLunTan.Filters;
using WqLunTan.Models.DataBase;
using Microsoft.Extensions.DependencyInjection;
using System.IO;

namespace WqLunTan.Areas.Manage.Controllers
{
    /// <summary>
    /// 后台文章管理控制器
    /// </summary>
    [Auth(AuthType = WqUserAuth.Manage)]
    public class ArticleController : BaseManageController
    {
        /// <summary>
        /// 后台修改公告页面
        /// </summary>
        /// <returns></returns>
        public IActionResult Notice()
        {
            var notice = DbContext.notice.FirstOrDefault() ?? new notice();
            return View(notice);
        }

        /// <summary>
        /// 更新公告内容
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> UpdateNotice(notice model)
        {
            var notice = DbContext.notice.FirstOrDefault();
            if (notice == null)
            {
                notice = new notice();
                notice.content = model.content;
                notice.is_show = model.is_show;
                notice.user_name = LoginUser.UserName;
                if (notice.create_time == DateTimeOffset.MinValue)
                {
                    notice.create_time = DateTimeOffset.UtcNow;
                }
                notice.last_update = DateTimeOffset.UtcNow;
                DbContext.notice.Add(notice);
            }
            else
            {
                notice.user_name = LoginUser.UserName;
                notice.content = model.content;
                notice.is_show = model.is_show;
                notice.last_update = DateTimeOffset.UtcNow;
            }

            try
            {
                httpCacheHelper.setCache("notice_layout", notice, 10);
                await DbContext.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null)
                {
                    return JsonExceptionError(new { ex.InnerException.Message, ex.InnerException.StackTrace });
                }
                return JsonExceptionError(new { ex.Message, ex.StackTrace });
            }

            return JsonOkResult("修改成功");
        }

        /// <summary>
        /// 可查看的分类文章
        /// </summary>
        /// <returns></returns>
        public IActionResult List(string search, int pageIndex = 1, int pageSize = 20)
        {
            List<article> list;

            var query = DbContext.article.Where(x => x.is_show);
            var page = new PageModel() { CurrentPageIndex = pageIndex };
            if (!string.IsNullOrWhiteSpace(search))
            {
                query = query.Where(x => x.title.Contains(search) || x.keywords.Contains(search));
                page.TotalCount = query.Count();
                list = query.OrderByDescending(x => x.top).ThenBy(x => x.sort_num).ThenByDescending(x => x.create_time).Skip(pageSize * pageIndex - pageSize).Take(pageSize).ToList();
            }
            else
            {
                page.TotalCount = query.Count();
                list = query.OrderByDescending(x => x.top).ThenBy(x => x.sort_num).ThenByDescending(x => x.create_time).Skip(pageSize * pageIndex - pageSize).Take(pageSize).ToList();
            }

            var uidlist = list.Select(x => x.uid).ToList();
            if (uidlist.Count > 0)
            {
                var ulist = DbContext.Users.Where(x => uidlist.Contains(x.Id)).ToList();
                ViewData["ulist"] = ulist;
            }
            else
            {
                ViewData["ulist"] = new List<WqUser>();
            }

            var cate = DbContext.art_category.OrderByDescending(x => x.is_show).ThenBy(x => x.sort).ThenBy(x => x.create_time).ToList();

            ViewData["page"] = page;
            ViewData["list"] = list;
            ViewData["cate"] = cate;
            ViewData["is_show"] = true;
            ViewData["show-count"] = DbContext.article.Where(x => x.is_show).Count();
            ViewData["hide-count"] = DbContext.article.Where(x => x.is_show == false).Count();
            return View();
        }

        public IActionResult HideList(string search, int pageIndex = 1, int pageSize = 20)
        {
            List<article> list;

            var query = DbContext.article.Where(x => x.is_show == false);
            var page = new PageModel() { CurrentPageIndex = pageIndex };
            if (!string.IsNullOrWhiteSpace(search))
            {
                query = query.Where(x => x.title.Contains(search) || x.keywords.Contains(search));
                page.TotalCount = query.Count();
                list = query.OrderByDescending(x => x.top).ThenBy(x => x.sort_num).ThenByDescending(x => x.create_time).Skip(pageSize * pageIndex - pageSize).Take(pageSize).ToList();
            }
            else
            {
                page.TotalCount = query.Count();
                list = query.OrderByDescending(x => x.top).ThenBy(x => x.sort_num).ThenByDescending(x => x.create_time).Skip(pageSize * pageIndex - pageSize).Take(pageSize).ToList();
            }

            var uidlist = list.Select(x => x.uid).ToList();
            if (uidlist.Count > 0)
            {
                var ulist = DbContext.Users.Where(x => uidlist.Contains(x.Id)).ToList();
                ViewData["ulist"] = ulist;
            }
            else
            {
                ViewData["ulist"] = new List<WqUser>();
            }

            var cate = DbContext.art_category.OrderByDescending(x => x.is_show).ThenBy(x => x.sort).ThenBy(x => x.create_time).ToList();

            ViewData["page"] = page;
            ViewData["list"] = list;
            ViewData["cate"] = cate;
            ViewData["is_show"] = false;
            ViewData["show-count"] = DbContext.article.Where(x => x.is_show).Count();
            ViewData["hide-count"] = DbContext.article.Where(x => x.is_show == false).Count();
            return View("List");
        }

        /// <summary>
        /// 文章添加页
        /// </summary>
        /// <returns></returns>
        public IActionResult Add()
        {
            var cate = DbContext.art_category.OrderByDescending(x => x.is_show).ThenBy(x => x.sort).ThenBy(x => x.create_time).ToList();
            ViewData["cate"] = cate;

            return View();
        }

        public IActionResult Save(article model, IFormFile img)
        {
            if (string.IsNullOrWhiteSpace(model.title))
            {
                return JsonParamError("文章标题不能为空");
            }
            if (string.IsNullOrWhiteSpace(model.keywords))
            {
                return JsonParamError("文章关键字不能为空");
            }
            if (string.IsNullOrWhiteSpace(model.content))
            {
                return JsonParamError("文章内容不能为空");
            }

            if (img != null)
            {
                var env = HttpContext.RequestServices.GetService<IHostingEnvironment>();
                var root = env.WebRootPath;

                var day = DateTimeOffset.UtcNow.ToString("yyyy-MM-dd");

                var ext = img.FileName.Substring(img.FileName.LastIndexOf('.'));
                var name = $"{Guid.NewGuid().ToString("N")}{ext}";
                var filename = Path.Combine(root, "upload", "image", day, name);
                var fi = new FileInfo(filename);
                if (!Directory.Exists(fi.DirectoryName))
                {
                    Directory.CreateDirectory(fi.DirectoryName);
                }
                using (var fs = System.IO.File.Create(filename))
                {
                    img.CopyTo(fs);
                }
                var fileUrl = $"/upload/image/{day}/{name}";
                model.img = fileUrl;
            }
            else
            {
                model.img = string.Empty;
            }
            model.create_time = DateTimeOffset.UtcNow;
            model.last_update = DateTimeOffset.UtcNow;
            model.uid = LoginUser.Id;
            DbContext.article.Add(model);
            DbContext.SaveChanges();

            return JsonOkResult("保存成功");
        }

        /// <summary>
        /// 查看文章详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public IActionResult Detail(Guid id)
        {
            var model = DbContext.article.Where(x => x.id == id).SingleOrDefault();
            if (model != null)
            {
                var cate = DbContext.art_category.OrderByDescending(x => x.is_show).ThenBy(x => x.sort).ThenBy(x => x.create_time).ToList();
                var user = DbContext.Users.Where(x => x.Id == model.uid).SingleOrDefault();
                ViewData["cate"] = cate;
                ViewData["user"] = user;
            }
            else
            {
                return NotFound();
            }

            return View(model);
        }

        public IActionResult Update(article model, IFormFile img)
        {
            if (string.IsNullOrWhiteSpace(model.title))
            {
                return JsonParamError("文章标题不能为空");
            }
            if (string.IsNullOrWhiteSpace(model.keywords))
            {
                return JsonParamError("文章关键字不能为空");
            }
            if (string.IsNullOrWhiteSpace(model.content))
            {
                return JsonParamError("文章内容不能为空");
            }
            if (!string.IsNullOrWhiteSpace(model.previous_url) && !model.previous_url.ToLower().StartsWith("/article/detail/"))
            {
                return JsonParamError("上一篇url格式不正确");
            }

            var art = DbContext.article.Where(x => x.id == model.id).SingleOrDefault();
            if (art == null)
            {
                return NotFound();
            }

            if (img != null)
            {
                var env = HttpContext.RequestServices.GetService<IHostingEnvironment>();
                var root = env.WebRootPath;

                var day = DateTimeOffset.UtcNow.ToString("yyyy-MM-dd");

                var ext = img.FileName.Substring(img.FileName.LastIndexOf('.'));
                var name = $"{Guid.NewGuid().ToString("N")}{ext}";
                var filename = Path.Combine(root, "upload", "image", day, name);
                var fi = new FileInfo(filename);
                if (!Directory.Exists(fi.DirectoryName))
                {
                    Directory.CreateDirectory(fi.DirectoryName);
                }
                using (var fs = System.IO.File.Create(filename))
                {
                    img.CopyTo(fs);
                }
                if (!string.IsNullOrWhiteSpace(art.img))
                {
                    var oldImage = $"{root.Replace('\\', '/').TrimEnd('/')}{art.img}";
                    if (System.IO.File.Exists(oldImage))
                    {
                        System.IO.File.Delete(oldImage);
                    }
                }
                var fileUrl = $"/upload/image/{day}/{name}";
                art.img = fileUrl;
            }

            if (!string.IsNullOrWhiteSpace(model.previous_url))
            {
                // 更新或者修改
                model.previous_url = model.previous_url.ToLower().TrimEnd('/');

                if (art.previous_url.Length > 0)
                {
                    var oldPrevGuid = art.previous_url.Replace("/article/detail/", "");
                    if (Guid.TryParse(oldPrevGuid, out var oldGuid))
                    {
                        var oldPrevArticle = DbContext.article.Where(x => x.id == oldGuid).SingleOrDefault();
                        if (oldPrevArticle != null)
                        {
                            oldPrevArticle.next_url = string.Empty;
                        }
                    }
                }

                if (Guid.TryParse(model.previous_url.Replace("/article/detail/", ""), out var preGuid))
                {
                    var prevArticle = DbContext.article.Where(x => x.id == preGuid).SingleOrDefault();
                    if (prevArticle != null)
                    {
                        prevArticle.next_url = $"/article/detail/{model.id.ToString()}";
                        art.previous_url = model.previous_url;
                    }
                }
            }

            art.cateid = model.cateid;
            art.title = model.title;
            art.content = model.content;
            art.keywords = model.keywords;
            art.top = model.top;
            art.sort_num = model.sort_num;
            art.is_show = model.is_show;
            DbContext.SaveChanges();

            return JsonOkResult("保存成功");
        }

    }
}